package com.app.util.db.tool;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import com.app.util.db.DBPool;
import com.app.util.db.bean.ResultMap;
import com.app.util.db.bean.TableDefined;
import com.app.util.db.enums.IDType;
import com.app.util.db.util.SqlNameTranser;

public class TableUID {

	private static final Map<String, AtomicLong> ids = new HashMap<String, AtomicLong>();

	private DBPool dbPool;

	public TableUID(DBPool dbPool) {
		this.dbPool = dbPool;
	}

	private AtomicLong getAtomicLong(TableDefined tableDefined) throws SQLException {
		String key = tableDefined.db() + "." + tableDefined.table();
		AtomicLong atomicLong = ids.get(key);
		if (null != atomicLong) {
			return atomicLong;
		}
		synchronized (ids) {
			atomicLong = ids.get(key);
			if (null == atomicLong) { 
				atomicLong = new AtomicLong();
				ids.put(key, atomicLong);
				Select select = new Select(dbPool);
				StringBuffer sqlSb = new StringBuffer("SELECT MAX(");
				sqlSb.append(SqlNameTranser.IT.toString(tableDefined.id()));
				sqlSb.append(") AS `max_id` FROM ");
				if (!tableDefined.db().isEmpty()) {
					sqlSb.append(SqlNameTranser.IT.toString(tableDefined.db())).append(".");
				}
				sqlSb.append(SqlNameTranser.IT.toString(tableDefined.table()));
				ResultMap rm = select.selectSingle(sqlSb.toString());
				if (null == rm.getInteger("max_id")) {
					atomicLong.set(0);
				} else {
					atomicLong.set(rm.getInteger("max_id"));
				}
			}
			return atomicLong;
		}
	}

	public Number next(TableDefined tableDefined) throws SQLException {
		long newID = getAtomicLong(tableDefined).addAndGet(1);
		if (tableDefined.idType() == IDType.Short) {
			if (newID > Short.MAX_VALUE) {
				throw new RuntimeException("Value max than Short.MAX_VALUE");
			}
		}
		if (tableDefined.idType() == IDType.Int) {
			if (newID > Integer.MAX_VALUE) {
				throw new RuntimeException("Value max than Integer.MAX_VALUE");
			}
		}
		return (int) newID;
	}

	public DBPool getDbPool() {
		return dbPool;
	}

}
